﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Cofe.Core;
using log4net;

namespace Cofe.Web.Feed
{
    public class FeedFileSystemHelper : IFeedFileSystemHelper
    {
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private static readonly XmlWriterSettings WriterSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true, CloseOutput = true };
        private static readonly XmlReaderSettings ReaderSettings = new XmlReaderSettings { CloseInput = true };

        public FeedFileSystemHelper(string currentFeedPath, string archiveFeedPath, string entryFeedPath)
        {
            System.IO.Directory.CreateDirectory(currentFeedPath);
            System.IO.Directory.CreateDirectory(archiveFeedPath);
            System.IO.Directory.CreateDirectory(entryFeedPath);

            CurrentFeedPath = currentFeedPath;
            ArchiveFeedPath = archiveFeedPath;
            EntryFeedPath = entryFeedPath;
        }

        public string getFeedPath(FeedDirectory dir)
        {
            switch (dir)
            {
                case FeedDirectory.Current:
                    return CurrentFeedPath;
                case FeedDirectory.Archive:
                    return ArchiveFeedPath;
                case FeedDirectory.Entry:
                    return EntryFeedPath;
            }
            throw new NotSupportedException();
        }

        public void CleanUpCurrentFeedDirectory(FeedId recentFeedId)
        {
            Log.Debug("Cleaning up current directory.");
            foreach (var f in
                new System.IO.DirectoryInfo(CurrentFeedPath)
                .GetFiles("*.atom").Where(fi => fileNameDoesNotEqualCurrentFileName(fi, recentFeedId) && fileIsMoreThanOneMinuteOld(fi)))
                f.Delete();
        }

        private static bool fileIsMoreThanOneMinuteOld(System.IO.FileInfo fileInfo)
        {
            return DateTime.Now.Subtract(fileInfo.LastWriteTime).TotalSeconds > 60;
        }

        private static bool fileNameDoesNotEqualCurrentFileName(System.IO.FileInfo fileInfo, FeedId recentFeedId)
        {
            return fileInfo.Name != recentFeedId.FileName;
        }

        public string GetLatestFeed()
        {
            var latestFile = new System.IO.DirectoryInfo(CurrentFeedPath)
                .GetFiles("*.atom").OrderByDescending(fi => fi.LastWriteTimeUtc).FirstOrDefault();
            return latestFile == null ? null : latestFile.Name;
        }

        public string GetETag(FeedId feedId)
        {
            string fullPath = PathFE.Combine(getFeedPath(feedId.FeedDirectory), feedId.FileName);
            var fileInfo = new System.IO.FileInfo(fullPath);

            return string.Format(@"""{0}#{1}""", fileInfo.Name, fileInfo.LastWriteTimeUtc.Ticks);
        }

        public bool IsExists(FeedDirectory dir, string fileName)
        {
            string filePath = PathFE.Combine(getFeedPath(dir), fileName);
            return System.IO.File.Exists(filePath);
        }

        public XmlReader GetXmlReader(FeedDirectory dir, string fileName)
        {
            string filePath = PathFE.Combine(getFeedPath(dir), fileName);            
            return XmlReader.Create(filePath, ReaderSettings);
        }

        public XmlWriter GetXmlWriter(FeedDirectory dir, string fileName)
        {
            string filePath = PathFE.Combine(getFeedPath(dir), fileName);
            return XmlWriter.Create(filePath, WriterSettings);
        }

        public string CurrentFeedPath { get; private set; }
        public string ArchiveFeedPath { get; private set; }
        public string EntryFeedPath { get; private set; }


      
    }
}
